'''
Created on 28/12/2010

@author: joaquin
@Poyecto: Gestor de nucleos para Fedora v.- 0.1 ALPHA
'''

# Paquetes a importar 
import os;
import commands;
import types;
from packagekit.client import PackageKitClient

# Aqui se guardan los kernel que se encuentran
global matches;

class Kernel:    
    def imprimirKernel(self):
        """Esta funcion imprime los kernels que hay en el sistema"""
        
        cont = 0;
        print("\n--- Kernels instalados en este sistema ---");
        for match in matches:
            print ("[" + str(cont) + "] " + str(match));
            cont = cont+1;
        
        print("Se ha encontrado un total de " + str(cont) + " kernel.");
    
    def numeroKernel(self):
        """Devuelve el numero de nucleos que hay en el sistema"""
        
        # Obtengo la cantidad de elementos almacenados
        num = len(matches);
        
        # No existe ningun nucleo
        if num==0:
            cont = 0;
        # Solo existe un nucleo
        elif num==1:
            cont = 1;
        # Existen varios nucleos
        else:
            cont = num;
        
        return cont;
    
    def obtenerKernel(self):
        """Obtiene los nucleos que hay en el sistema"""
        
        # Tablas donde guardo los nucleos
        tablaPAE = [];
        tablaNormal = [];
        
        if pk.resolve("kernel-PAE", "installed"):
            print(">>> Detectado kernel PAE (Phisical Address Extension).");
            tablaPAE = pk.resolve("kernel-PAE", "installed");
            for pae in tablaPAE:
                print(pae);
        
        if pk.resolve("kernel", "installed"):
            print(">>> Detectado kernel.");
            tablaNormal = pk.resolve("kernel", "installed");
            for normal in tablaNormal:
                print(normal);
        
        # Obtengo la cantidad de nucleos total
        suma = len(tablaPAE) + len(tablaNormal);
        cont = 0;
        
        # Para poder eliminar algun nucleo, necesito dos o mas
        if suma==0 | suma==1:
            print("No existen los nucleos suficientes para realizar la accion.");
        else:
            while cont < suma:
                for pae in tablaPAE:
                    matches.append(pae);
                    cont = cont +1;
                
                for normal in tablaNormal:
                    matches.append(normal);
                    cont = cont + 1;
        
            print("Hay un total de " + str(cont) + " nucleos.");

    def eliminarEnUso(self):
        """Elimina el kernel en uso de la lista de nucleos"""
        
        items = [];
        cont = 0;
        
        # Obtengo el nucleo actual
        nActual = commands.getoutput("uname -r");
        
        # Si el nucleo es PAE.
        if nActual[-3:] == "PAE":
            nucleo = "kernel-PAE-" + nActual[:-4];
        # En otro caso, sera un nucleo normal.
        else:
            nucleo = "kernel-" + nActual;
        
        for item in matches:
            nombre = str(item);
            if nucleo == nombre:
                elemento = item;
                break;
            else:
                cont = cont + 1;
        
        matches.remove(elemento);
        
if __name__ == '__main__':
    kn = Kernel();
    pk = PackageKitClient();
    salir = False;
    matches = [];

    os.system("clear");
    print("---- ACUERDO DE USO ----");
    print("El siguiente script escrito en python sirve para eliminar nucleos en desuso\n" \
    "del sistema operativo Fedora.\n" \
    "El script ha sido creado por Joaquin Gutierrez Gil y publicado en su blog\n" \
    "personal el 8/3/2011 en su version 0.1 BETA (http://www.informatizando.es)\n" \
    "Joaquin Gutierrez Gil no se hace responsable del uso y/o danos que pueda ocasionar\n" \
    "este script en su ordenador, por lo que uselo bajo su propia responsabilidad.\n" \
    "El script ha sido probado con exito en la distribucion Fedora 14, tanto en un\n" \
    "sistema de 32 bits como de 64.\n" \
    "Este script se libera bajo la licencia GNU GPL V3.\n" \
    "Si continua con el uso del script, acepta el presente acuerdo.\n");
    print("Acepta el acuerdo? (si/no)");
    respuesta = str(raw_input());
    
    # Compruebo la respuesta del usuario
    if respuesta == "si" or respuesta == "SI":
        # Compruebo si esta logueado como root o no
        if not os.geteuid():
            
            # Obtengo los nucleos
            kn.obtenerKernel();
            
            # Kernels que se han encontrado
            #for match in matches:
            #    print(match);
            
            # Cuantos se han encontrado
            kernel = kn.numeroKernel();
    
            # ************ MENU ***************
            if kernel == 0 and kernel == 1:
                print("Deteniendo la ejecucion");
            else:
                while not salir and kernel>1:
                    kn.eliminarEnUso();
                    kn.imprimirKernel();
                    actual = commands.getoutput("uname -r");
                    print(">>> Elige el kernel a desinstalar <<<");
                    print(" - Escribe el numero del kernel que quieres desinstalar: ");
                    print(" - Escribe '-1' para terminar la ejecucion.");
                    print("\nActualmente esta usando el siguiente kernel: " + actual);
                    print("\nNOTA: Tenga cuidado en no seleccionar el kernel en uso.\n" \
                          "Este script elimina de la lista de nucleos el actual en uso,\n" \
                          "si su nucleo no se encuentra en la lista, puede eliminarlos todos.\n" \
                          "Si su nucleo aparece en la lista por ERROR, tenga cuidado de NO ELIMINARLO.");
                    print("SELECCIONE UNA OPCION: ");
                    opcion = int(raw_input());
                    
                    if opcion == -1:
                        print("Hasta pronto.");
                        salir = True;
                    elif opcion>=0 and opcion<kernel:
                        print("Se va a desinstalar el siguiente el kernel: " + str(matches[opcion]));
                        print("Continuar? (si/no): ");
                        respuesta = str(raw_input());
                        
                        if respuesta == "si":
                            try:
                                print("Eliminando el nucleo seleccionado, espere hasta finalizar todas las operaciones...");
                                pk.remove_packages(matches[opcion]);
                                matches.remove(matches[opcion]);
                                kernel = kernel - 1;
                            except:
                                print("No ha sido posible eliminar el kernel.");
                            finally:
                                print("Terminando la ejecucion...");
                        else:
                            print("No ha contestado correctamente, intentelo de nuevo.");
                    else:
                        print("Has introducido un valor no valido.");
        else:
            print ("Necesitas ejecutar el programa como ROOT");
    else:
        print(">>> Hasta otra <<<");